home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1994-03-21 | 24.5 KB | 894 lines |
- %{
- #define YYDEBUG 0
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <alloc.h>
- #include <string.h>
- #include "t_cio.h"
- #include "vector.h"
- #include "t_lex.h"
- #include "bstone_m.h"
- LEX *lex;
- FILE *errlogz=stderr;
- FILE *pvp=stdout;
- int ybdebug=0;
- int load_flag=0;
- int fkt_id;
- POV_OBJ **obj_all;
- static int i,id1,id2,k;
- static DIM_H dm;
- static long n;
- static T_NODE *tn;
- static FT_LOOP *ft;
- static double dd;
- static double *dp;
- static POV_OBJ pv_obj;
- static char pv_line[LSIZE];
- static int n_obj;
- static POV_OBJ *obj_lst[BSIZE];
- static POV_OBJ *pv;
- static VECTOR v;
- static char *ys;
-
- %}
- %TOKEN Y_VAL Y_VEC Y_ABS Y_STR Y_END Y_REM Y_GOTO Y_TRACE
- Y_LET Y_PRINT Y_LIST Y_OBJ Y_V0 Y_VX Y_VY Y_VZ
- Y_LOAD Y_SAVE Y_IF Y_THEN Y_CONT Y_STOP Y_GOSUB Y_RETURN
- Y_DELETE Y_NUM Y_DIM Y_FOR Y_TO Y_STEP Y_NEXT Y_NEW Y_RUN
- Y_FKT Y_RND Y_FOPEN Y_FPRINT Y_PLANE Y_BIT Y_BOUND Y_TEX
- Y_TRANSFORM
- %union { double s; double v[3]; T_NODE *t; POV_OBJ *p; }
- %type <s> i_expr
- %type <s> i_exprx
- %type <s> i_expry
- %type <s> i_exprz
- %type <s> i_term
- %type <s> i_faktor
- %type <s> f_step
- %type <v> v_expr
- %type <v> v_exprz
- %type <v> v_term
- %type <v> v_faktor
- %type <t> Y_VEC
- %type <t> y_vec
- %type <t> Y_VAL
- %type <t> y_val
- %type <t> Y_NUM
- %type <t> Y_STR
- %type <p> Y_OBJ
- %type <p> y_obj
- %%
- anw : { if(ybdebug && !transl_flag)
- {
- if(program_ctr>=0)
- fprintf(errlogz,"* %-6d ",program[program_ctr-1].n);
- else fprintf(errlogz,"* C ");
- fprintf(errlogz,"%s\n",retransl_line(clines));
- }
- } anwg
- { if(!transl_flag)
- { if(ybdebug==1)
- {
- #ifdef __TURBOC__
- fprintf(stderr,"* %ld Bytes free\n",coreleft());
- #endif
- putc('*',stderr);
- gets(tmp_line); /* TRAP */
- if(tmp_line[0] && (tmp_line[0]!='y') && (tmp_line[0]!='Y'))
- { if(program_ctr>=0) cont_line=program[program_ctr].n;
- program_ctr=-1; }
- }
- /* perform DOS-action */
- #ifdef __MSDOS__
- if(break_en) { putchar('\r'); }
- #endif
- if(break_req)
- { break_req=0;
- if(program_ctr>=0) cont_line=program[program_ctr].n;
- if(program_ctr>=0)
- printf(".. break at line %d\n",cont_line);
- program_ctr=-1; }
- }}
-
- anwg :
-
- | Y_END { if(!transl_flag) program_ctr=-1; }
-
- | Y_STOP { if(!transl_flag)
- { if(program_ctr>=0) cont_line=program[program_ctr].n;
- if(program_ctr>=0)
- printf(".. stopped at line %d\n",cont_line);
- program_ctr=-1; }}
-
- | Y_CONT { if(!transl_flag)
- if(cont_line>=0) program_ctr=search_line(cont_line); }
-
- | Y_REM
- { if(transl_flag)
- { do
- {
- lex=t_lex(NULL,LEX_RCHAR);
- cline[clinep++]=(char)(id1=lex->wert.n.i);
- }
- while((id1!='\n') && (lex->typ!=EOLX));
- clinep-=1;
- lex->typ=EOLN; t_lex(NULL,LEX_PUSH);
- }
- else for(;*(clines+clinep)!=(char)0;clinep++);
- }
-
- | Y_IF i_expr Y_THEN
- { if(!transl_flag && !($2))
- for(;*(clines+clinep)!=(char)0;clinep++); }
- anwg
-
- | Y_IF i_expr Y_GOTO Y_NUM
- { if(!transl_flag && ($2))
- program_ctr=search_line((int)(*(VEC)(($4)->p))); }
-
-
- | Y_GOTO Y_NUM
- { if(!transl_flag) program_ctr=search_line((int)(*(VEC)(($2)->p))); }
-
- | Y_RUN { if(!transl_flag)
- { gosub_ptr=0; program_ctr=0; }}
- | Y_RUN i_expr { if(!transl_flag)
- { gosub_ptr=0;
- program_ctr=search_line((int)($2)); }}
-
- | Y_GOSUB Y_NUM
- { if(!transl_flag)
- { if(gosub_ptr>=MAX_LINES/10)
- t_error("Gosub stack overflow.",4);
- if(program_ctr>=0)
- gosub_stack[gosub_ptr++]=program[program_ctr].n;
- else
- gosub_stack[gosub_ptr++]=-1;
- program_ctr=search_line((int)(*(VEC)(($2)->p)));
- }}
-
- | Y_RETURN
- { if(!transl_flag)
- { if(gosub_ptr==0) { yyerror("return without gosub"); YYABORT; }
- i=gosub_stack[--gosub_ptr];
- program_ctr=search_line(i);
- }}
-
- | Y_FOR Y_VAL '=' i_expr Y_TO i_expr f_step
- { if(transl_flag)
- {
- tn=($2)->a;
- if(tn!=(T_NODE *)NULL)
- if(tn->c!=B_FOR)
- { yyerror("variable unsuitable for loop"); YYABORT; }
- sprintf(tmp_line,"?%s",($2)->s);
- if((tn=t_symtable(tmp_line))==(T_NODE *)NULL)
- t_error("Problem with FOR-loop.",-1);
- if(tn->p==(void *)NULL)
- {
- if((tn->p=(void *)malloc(sizeof(FT_LOOP)))
- ==(void *)NULL) t_error("No memory for loop.",1);
- ft=(FT_LOOP *)(tn->p);
- ft->n=-1; ft->start=0;
- ft->step=1; ft->end=0;
- tn->c=B_FOR;
- }
- ($2)->a=tn;
- }
- else /* !transl_flag */
- { tn=($2)->a;
- if((tn==(T_NODE *)NULL) || (tn->c!=B_FOR))
- t_error("Unknown loop, probably array",-1);
- ft=(FT_LOOP *)(tn->p);
- if(program_ctr>0) ft->n=program[program_ctr-1].n+1;
- else { yyerror("FOR outside program"); YYABORT; }
- ft->start=$4; ft->step=$7; ft->end=$6;
- *(VEC)(($2)->p)=ft->start; }
- }
-
- | Y_NEXT Y_VAL
- { if(!transl_flag)
- { tn=($2)->a;
- if((tn==(T_NODE *)NULL) || (tn->p==(void *)NULL)
- || (tn->c!=B_FOR))
- { yyerror("NEXT without FOR"); YYABORT; }
- ft=(FT_LOOP *)(tn->p);
- if(*(VEC)(($2)->p)+ft->step <= ft->end)
- { *(VEC)(($2)->p)+=ft->step;
- program_ctr=search_line(ft->n); }
- if(ybdebug)
- fprintf(errlogz,"* loop %G **\n",*(VEC)($2->p));
- }}
-
-
-
- | Y_TRACE i_expr
- { if(!transl_flag) ybdebug=($2);
- switch(ybdebug)
- {
- case 1: errlogz=stderr; break;
- case 2: errlogz=errlog; break;
- case 3: errlogz=stderr; break;
- }
- }
-
- | Y_NEW { if(!transl_flag) { new(); program_ctr=-1; }}
-
- | Y_LET asn_expr
- | asn_expr
-
- | Y_DIM Y_VAL dims
- { if(!transl_flag)
- { for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
- if(n<=0) { yyerror("scalar field dimension <=0"); YYABORT; }
- if(ybdebug)
- fprintf(errlogz,"* s size %ld **\n",n);
- mkfield($2,&dm,n);
- }}
-
- | Y_DIM Y_VEC dims
- { if(!transl_flag)
- { for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
- n*=3;
- if(n<=0) { yyerror("vector field dimension <=0"); YYABORT; }
- if(ybdebug)
- fprintf(errlogz,"* v size %ld **\n",n);
- mkfield($2,&dm,n);
- }}
-
- | Y_DIM Y_BIT Y_VAL dims /* last dim is bit number */
- { if(!transl_flag)
- { for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
- if(n<=0) { yyerror("bit field dimension <=0"); YYABORT; }
- n=(n-1)/(8*sizeof(double))+1;
- if(ybdebug)
- fprintf(errlogz,"* b size %ld*%d **\n",n,sizeof(double));
- mkfield($3,&dm,n);
- }}
-
- | Y_PRINT pr_exprs { if(!transl_flag) printf("\n"); }
-
- | Y_FPRINT fp_exprs { if(!transl_flag) fprintf(pvp,"\n"); }
-
- | Y_LIST lst_expr
- { if(!transl_flag) {
- for(i=id1,n=0; (i<=id2) && (program[i].n>=0); i++,n++)
- { printf("%-6d# %s\n",program[i].n,
- retransl_line(program[i].s));
- if(n && !(n%20)) gets(tmp_line);
- }
- printf("\n");
- }}
-
- | Y_LOAD Y_STR
- { if(!transl_flag)
- { if(flev>=9) t_error("Maximum file depth reached.",4);
- if((fp[++flev]=fopen((($2)->s)+1,"r"))==NULL)
- { sprintf(err_msg,"can't open command file: %s",
- (($2)->s)+1);
- yyerror(err_msg); flev-=1; YYABORT; }
- load_flag=1; }}
-
- | Y_SAVE lst_expr Y_STR
- { if(!transl_flag)
- if(save_program(id1,id2,(($3)->s)+1)==NULL)
- { sprintf(err_msg,"can't open save file: %s",(($3)->s)+1);
- yyerror(err_msg); YYABORT; }
- }
-
- | Y_SAVE Y_TRACE Y_STR
- { if(!transl_flag)
- { transl_flag=2;
- if(save_program(0,MAX_LINES,(($3)->s)+1)==NULL)
- { sprintf(err_msg,"can't open save file: %s",(($3)->s)+1);
- yyerror(err_msg); YYABORT; }
- transl_flag=0;
- }
- }
-
- | Y_FOPEN { if(!transl_flag)
- { if(pvp!=stdout) fclose(pvp);
- pvp=stdout;
- }}
- | Y_FOPEN Y_STR
- { if(!transl_flag)
- { if(pvp!=stdout) fclose(pvp);
- if((pvp=fopen((($2)->s)+1,"a"))==NULL)
- { sprintf(err_msg,"can't open output file: %s",
- (($2)->s)+1);
- yyerror(err_msg); YYABORT; }
- }}
-
- | Y_DELETE lst_expr
- { if(!transl_flag)
- for(i=id1; (i<=id2) && (program[id1].n>=0); i++)
- insert_line(program[id1].n, (char *)NULL); }
- | Y_DELETE Y_STR
- { if(!transl_flag)
- { if(pvp!=stdout) fclose(pvp);
- if((pvp=fopen((($2)->s)+1,"w"))==NULL)
- { sprintf(err_msg,"can't open output file: %s",
- (($2)->s)+1);
- yyerror(err_msg); YYABORT; }
- }}
- | Y_DELETE Y_OBJ
- { if(!transl_flag)
- { free_obj($2);
- if(ybdebug) obj_deb($2,0,errlogz);
- }}
- | Y_DELETE Y_TEX Y_OBJ
- { if(!transl_flag)
- { del_obj(($3)->tex); ($3)->tex=(POV_OBJ *)NULL;
- if(ybdebug) obj_deb($3,0,errlogz);
- }}
- | Y_DELETE Y_BOUND Y_OBJ
- { if(!transl_flag)
- { del_obj(($3)->bound); ($3)->bound=(POV_OBJ *)NULL;
- if(ybdebug) obj_deb($3,0,errlogz);
- }}
-
- | Y_BOUND Y_OBJ
- { if(!transl_flag) {
- bound_obj($2); if(ybdebug) obj_deb($2,0,errlogz); }}
-
- f_step : { $$=1; }
- | Y_STEP i_expr { $$=$2; }
-
- asn_expr: y_val '=' i_expr { if(!transl_flag) *(VEC)(($1)->p)=$3; }
-
- | Y_BIT Y_VAL dims '=' i_expr
- { if(!transl_flag)
- {
- dp=get_field(-sizeof(double),$2,&dm);
- if(dp==(VEC)NULL) YYABORT;
- id2=id1%(sizeof(int)*8); id1=id1/(sizeof(int)*8);
- i=*((int *)dp+id1);
- k=1; k=k<<id2; i=($5!=0) ? i|k : i&~k;
- *((int *)dp+id1)=i;
- }}
-
- | y_vec '=' v_expr
- { if(!transl_flag)
- for(i=0; i<3; i++) *((VEC)(($1)->p)+i)=($3)[i]; }
-
- | Y_OBJ '=' Y_STR
- { if(!transl_flag)
- { pv=$1;
- if((pv->c>0) && (pv->s!=(char *)NULL))
- for(ys=pv->s;*ys; ys+=5) del_obj(obj_all[get4hex(ys+1)]);
- pv->c=0;
- if(pv->s!=(char *)NULL) free(pv->s);
- pv->s=cp_str((($3)->s)+1);
- if(ybdebug) obj_deb($1,0,errlogz);
- }}
-
- | Y_OBJ '=' y_obj
- { if(!transl_flag)
- { obj_asn($1,$3);
- if(ybdebug) obj_deb($1,0,errlogz);
- }}
-
- | Y_OBJ '=' v_expr { if(!transl_flag) vecasn(($1)->b,$3); }
-
- | Y_TEX Y_OBJ '=' y_obj
- { if (!transl_flag)
- { pv=($2)->tex;
- if(pv!=(POV_OBJ *)NULL) { del_obj(pv); pv=(POV_OBJ *)NULL; }
- ($2)->tex=obj_asn(pv,$4);
- if(ybdebug) obj_deb($2,0,errlogz);
- }}
-
- | Y_BOUND Y_OBJ '=' y_obj
- { if (!transl_flag)
- { pv=($2)->bound;
- if(pv!=(POV_OBJ *)NULL) { del_obj(pv); pv=(POV_OBJ *)NULL; }
- ($2)->bound=obj_asn(pv,$4);
- if(ybdebug) obj_deb($2,0,errlogz);
- }}
-
-
- pr_exprs: pr_expr
- | pr_expr ',' pr_exprs
-
- pr_expr : Y_STR { if(!transl_flag) printf("%s",(($1)->s)+1); }
- | i_expr { if(!transl_flag) printf(" %G",$1); }
- | v_expr { if(!transl_flag)
- printf(" <%G,%G,%G>",($1)[0],($1)[1],($1)[2]); }
- | Y_OBJ { if(!transl_flag) print_obj(stdout,$1); }
-
- fp_exprs: fp_expr
- | fp_expr ',' fp_exprs
-
- fp_expr : Y_STR { if(!transl_flag) fprintf(pvp,"%s ",(($1)->s)+1); }
- | i_expr { if(!transl_flag) fprintf(pvp," %G",$1); }
- | v_expr { if(!transl_flag)
- fprintf(pvp," <%G,%G,%G>",($1)[0],($1)[1],($1)[2]); }
- | Y_OBJ { if(!transl_flag) print_obj(pvp,$1); }
-
- lst_expr: { id1=0;id2=MAX_LINES; }
- | i_expr { id1=search_line((int)($1)); id2=MAX_LINES;}
- | i_expr ',' i_expr { id1=search_line((int)($1));
- id2=search_line((int)($3)); }
-
- dims : { dm.n=0; } dimsz
-
- dimsz : dim
- | dim dimsz
-
- dim : '[' i_exprx ']'
- { if(!transl_flag)
- { if(dm.n>=MAXDIM)
- { sprintf(err_msg,"More than %d dimensions.",MAXDIM);
- t_error(err_msg,4); }
- dm.d[dm.n++]=(long)$2;
- if(ybdebug)
- fprintf(errlogz,"* dim [%d] **\n",dm.d[dm.n-1]);
- }}
-
- obj_set : Y_OBJ ',' { obj_lst[0]=$1; n_obj=1; } obj_sez
-
- obj_sez : s_obj
- | s_obj ',' obj_sez
-
- s_obj : Y_OBJ { if(!transl_flag)
- { if(n_obj>=BSIZE) t_error("Too many objects",4);
- obj_lst[n_obj++]=$1; }}
-
- i_expr : i_exprx { $$=$1;
- if(ybdebug && !transl_flag)
- fprintf(errlogz,"* scalar %G **\n",$$);
- }
-
- v_expr : v_exprz { $$[0]=$1[0]; $$[1]=$1[1]; $$[2]=$1[2];
- if(ybdebug && !transl_flag)
- fprintf(errlogz,"* vector <%G,%G,%G> **\n",
- $$[0],$$[1],$$[2]);
- }
-
- i_exprx : i_expry { $$=$1; }
- | i_exprx '&' '&' i_expry { $$=(($1)&&($4)); }
- | i_exprx '|' '|' i_expry { $$=(($1)||($4)); }
-
-
- i_expry : i_exprz { $$=$1; }
- | i_expry '<' i_exprz { $$=(($1)< ($3)); }
- | i_expry '<' '=' i_exprz { $$=(($1)<=($4)); }
- | i_expry '=' i_exprz { $$=(($1)==($3)); }
- | v_exprz '=' v_exprz { $$=((($1)[0]==($3)[0]) &&
- (($1)[1]==($3)[1]) &&
- (($1)[2]==($3)[2])); }
- | i_expry '>' i_exprz { $$=(($1)> ($3)); }
- | i_expry '>' '=' i_exprz { $$=(($1)>=($4)); }
- | i_expry '!' '=' i_exprz { $$=(($1)!=($4)); }
- | v_exprz '!' '=' v_exprz { $$=((($1)[0]!=($4)[0]) ||
- (($1)[1]!=($4)[1]) ||
- (($1)[2]!=($4)[2])); }
-
- i_exprz : i_term { $$=$1; }
- | i_exprz '+' i_term { $$=(($1)+ ($3)); }
- | i_exprz '-' i_term { $$=(($1)- ($3)); }
-
- i_term : i_faktor { $$=$1; }
- | i_term '*' i_faktor { $$=(($1)* ($3)); }
- | v_term '*' v_faktor { $$=dot($1,$3); }
- | i_term '/' i_faktor { if(transl_flag) $$=0;
- else if($3!=0) $$=(($1)/ ($3));
- else {
- yyerror("division by zero");
- YYABORT; }}
- | i_term '%' i_faktor { $$=fmod($1,$3); }
-
- i_faktor: '-' i_faktor { $$=-($2); }
- | '!' i_faktor { $$=!($2); }
- | '@' i_faktor { $$=($2)*M_PI/180; }
- | '(' i_exprx ')' { $$=$2; }
- | Y_ABS '(' i_exprx ')' { $$=fabs($3); }
- | Y_ABS '(' v_exprz ')' { $$=vecabs($3); }
- | y_val { $$=*(VEC)(($1)->p); }
- | Y_NUM { $$=*(VEC)(($1)->p); }
- | Y_RND '(' i_exprx ')' { $$=rnd($3); }
- | Y_VX '(' v_exprz ')' { $$=$3[0]; }
- | Y_VY '(' v_exprz ')' { $$=$3[1]; }
- | Y_VZ '(' v_exprz ')' { $$=$3[2]; }
- | Y_FKT '(' i_exprx ')'
- { if(!transl_flag) switch(fkt_id)
- { case SIN: $$=sin($3); break;
- case COS: $$=cos($3); break;
- case TAN: dd=cos($3);
- if(dd==0) goto math_err;
- $$=sin($3)/dd; break;
- case ASIN: if(($3>1) || ($3<-1)) goto math_err;
- $$=asin($3); break;
- case ACOS: if(($3>1) || ($3<-1)) goto math_err;
- $$=acos($3); break;
- case ATAN: if(2*fabs($3)==M_PI/2) goto math_err;
- $$=atan($3); break;
- case EXP: $$=exp($3); break;
- case LOG: if($3<=0) goto math_err;
- $$=log($3); break;
- case SQRT: if($3<0) goto math_err;
- $$=sqrt($3); break;
- case SQR: $$=$3*$3; break;
- math_err: yyerror("math error"); YYABORT;
- default: yyerror("wrong scalar->scalar function"); YYABORT;
- }
- else $$=0; }
- | Y_FKT '(' i_exprx ',' i_exprx ')'
- { if(!transl_flag) switch(fkt_id)
- { case POW: $$=pow(($3),($5)); break;
- default: yyerror("wrong 2scalar->scalar function"); YYABORT;
- }
- else $$=0;
- }
- | Y_BIT Y_VAL dims
- { if(!transl_flag)
- {
- dp=get_field(-sizeof(double),$2,&dm);
- if(dp==(VEC)NULL) YYABORT;
- i=*((int *)dp+id1/(sizeof(int)*8));
- $$=(double)((i>>(id1%(sizeof(int)*8)))&1);
- }
- else $$=0;
- }
-
- y_val : Y_VAL { $$=$1; }
- | Y_VAL dims
- { if(!transl_flag)
- if(get_field(1,$1,&dm)==(VEC)NULL) YYABORT;
- $$=$1; }
-
- v_exprz : v_term { vecasn($$,$1); }
- | v_exprz '+' v_term { vecadd($$,$1,$3); }
- | v_exprz '-' v_term { vecsub($$,$1,$3); }
-
- v_term : v_faktor { vecasn($$,$1); }
- | i_term '*' v_faktor { vecmul($$,$1,$3); }
- | v_term '#' v_faktor { vecprod($$,$1,$3); }
-
- v_faktor: '(' v_exprz ')' { vecasn($$,$2); }
- | '<' i_exprz ',' i_exprz ',' i_exprz '>'
- { ($$)[0]=$2; ($$)[1]=$4; ($$)[2]=$6; }
- | y_vec
- { for(i=0; i<3; i++) $$[i]=*((VEC)(($1)->p)+i); }
- | '-' v_faktor { vecneg($$,$2); }
- | '@' v_faktor { vecscale($$,M_PI/180,$2); }
- | Y_RND '(' v_exprz ')' { for(i=0;i<3;i++) $$[i]=rnd(($3)[i]); }
- | Y_V0 { $$[0]=0; $$[1]=0; $$[2]=0; }
- | Y_VX { $$[0]=1; $$[1]=0; $$[2]=0; }
- | Y_VY { $$[0]=0; $$[1]=1; $$[2]=0; }
- | Y_VZ { $$[0]=0; $$[1]=0; $$[2]=1; }
- | Y_V0 '(' Y_OBJ ')' { vecasn($$,$3->b); }
- | Y_VX '(' Y_OBJ ')' { vecasn($$,$3->u); }
- | Y_VY '(' Y_OBJ ')' { vecasn($$,$3->v); }
- | Y_VZ '(' Y_OBJ ')' { vecasn($$,$3->w); }
- | Y_FKT '(' v_exprz ',' v_exprz ')'
- { if(!transl_flag) switch(fkt_id)
- { case ROT: rotxyz($$,$3,$5); break;
- case SCA: scale($$,$3,$5); break;
- case PER: if(($3)[0]==0 && ($3)[1]==0 && ($3)[2]==0)
- vecasn($$,$5);
- else
- { dd=dist2($3,$5); vecscale($$,dd,$3); }
- break;
- default: yyerror("wrong vector->vector function"); YYABORT;
- }
- else $$[0]=$$[1]=$$[2]=0;
- }
- | Y_TRANSFORM '#' '(' v_exprz ',' v_exprz ',' v_exprz ',' v_exprz ')'
- { if(!transl_flag) transformc($$,$4,$6,$8,$10); }
-
- | Y_TRANSFORM '(' v_exprz ',' v_exprz ',' v_exprz ',' v_exprz ')'
- { if(!transl_flag)
- { i=transformd($$,$3,$5,$7,$9);
- if(!i) { yyerror("transformation impossible"); YYABORT; }
- }}
-
- y_vec : Y_VEC { $$=$1; }
- | Y_VEC dims
- { if(!transl_flag)
- if(get_field(3,$1,&dm)==(VEC)NULL) YYABORT;
- $$=$1; }
-
-
- y_obj : Y_OBJ { $$=$1; }
-
- | Y_TEX Y_OBJ
- { if(!transl_flag)
- if(($2)->tex!=(POV_OBJ *)NULL) $$=($2)->tex;
- else { yyerror("Obj doesn't have a texture"); YYABORT; }
- }
-
- | Y_BOUND Y_OBJ
- { if(!transl_flag)
- if(($2)->bound!=(POV_OBJ *)NULL) $$=($2)->bound;
- else { yyerror("Obj doesn't have a bounding shape"); YYABORT; }
- }
-
- | Y_PLANE '(' v_expr ',' v_expr ')'
- { if(!transl_flag) $$=plane($3,$5); }
-
- | Y_PLANE '(' v_expr ',' v_expr ',' v_expr ')'
- { if(!transl_flag)
- { mknormal(v,$3,$5,$7);
- $$=plane($3,v);
- }}
-
-
- | Y_FKT '(' Y_OBJ ',' v_expr ')'
- { if(!transl_flag)
- { pv=cp_tmp($3);
- switch(fkt_id)
- { case SCALE: $$=yscale1(pv,$5); break;
- case ROTATE: $$=yrot1(pv,$5); break;
- case TRANSLATE: $$=ytransl1(pv,$5); break;
- default: yyerror("wrong obj/vec->obj function");
- YYABORT;
- }
- }
- else $$=$3;
- }
-
- | Y_FKT '#' '(' Y_OBJ ',' v_expr ')'
- { if(!transl_flag)
- { pv=cp_tmp($4);
- switch(fkt_id)
- { case SCALE: $$=yscale2(pv,$6); break;
- case ROTATE: $$=yrot2(pv,$6); break;
- case TRANSLATE: $$=ytransl2(pv,$6); break;
- default: yyerror("wrong obj/vec->obj function(#)");
- YYABORT;
- }
- }
- else $$=$4;
- }
-
- | Y_FKT '(' obj_set ')'
- { if(!transl_flag) switch(fkt_id)
- { case CTDS:
- if(n_obj<=2)
- { if(($$=ctds(obj_lst[0],obj_lst[1]))==(POV_OBJ *)NULL)
- { yyerror("ctds(2): object contains object");
- YYABORT; }}
- else
- {
- for(i=0;i<n_obj-1;i++)
- { if((pv=ctds(obj_lst[i],obj_lst[i+1]))
- ==(POV_OBJ *)NULL)
- { yyerror("ctds(n): object contains object");
- YYABORT; }
- obj_lst[i]=new_obj();
- if(strlen(pv->s)>=LSIZE-1)
- t_error("Too much dots to connect.",4);
- obj_lst[i]->s=cp_str(pv->s);
- vecasn(obj_lst[i]->b,pv->b);
- vecasn(obj_lst[i]->u,pv->u);
- vecasn(obj_lst[i]->v,pv->v);
- vecasn(obj_lst[i]->w,pv->w);
- }
- n_obj-=1; k=1;
- goto la_csg0;
- }
- break;
- case UNION: k=1; goto la_csg0;
- case SECT: k=2; goto la_csg0;
- case DIFF: k=3; goto la_csg0;
- case ADDOBJ:
- pv=obj_lst[0];
- if(pv->c==0) { k=1; goto la_csg0; }
- add_objz(pv);
- /* pv will be copied !! */
- k=pv->c;
- cp_tmp(pv);
- pv_obj.cnt=-1; pv_obj.c=1;
- pv_obj.s=cp_str(pv->s);
-
- for(i=1;i<n_obj;i++)
- add_obj(&pv_obj,obj_lst[i]);
- goto la_csg1;
-
- la_csg0: /* Adding to empty tmp object */
- vec0(pv_obj.b); vecx(pv_obj.u);
- vecy(pv_obj.v); vecz(pv_obj.w);
- pv_obj.cnt=-1; pv_obj.c=1;
- pv_obj.s=(char *)NULL;
- pv_obj.tex=(POV_OBJ *)NULL;
- pv_obj.bound=(POV_OBJ *)NULL;
-
- for(i=0;i<n_obj;i++)
- add_obj(&pv_obj,obj_lst[i]);
-
- la_csg1: if(pv_obj.s!=(char *)NULL)
- { if(strlen(pv_obj.s)>=LSIZE-1)
- t_error("Too much objects in CSG.",4);
- strcpy(pv_line,pv_obj.s);
- free(pv_obj.s);
- pv_obj.s=pv_line;
- }
- pv_obj.c=k;
- $$=&pv_obj;
- break;
-
- default: yyerror("wrong obj_set->obj function");
- YYABORT;
- }
- else $$=&pv_obj;
- }
-
- %%
- int yyerror(char *s)
- {
- fprintf(stderr,"%s : %s\n",yysccsid,s);
- if(errlog!=stderr) fprintf(errlog,"YACC : %s\n",s);
- return(0);
- }
-
- void mkfield(T_NODE *tt, DIM_H *dm, long n)
- {
- DIM_H *dmp;
- T_NODE *tn;
- static char msg[]="DIM array";
- int i; long l;
-
- sprintf(tmp_line,"[]%s",tt->s);
- if((tn=t_symtable(tmp_line))==(T_NODE *)NULL) t_error(msg,-1);
- tt->a=tn;
-
- if(tn->p!=(void *)NULL) free((dmp=(DIM_H *)(tn->p))->f); /* kill field */
- else { tn->p=(void *)(dmp=(DIM_H *)malloc(sizeof(DIM_H)));
- if(dmp==(DIM_H *)NULL) t_error("Dim",1); }
-
- tn->c=B_FLD; dmp->n=dm->n;
- for(i=0;i<dmp->n;i++) dmp->d[i]=dm->d[i];
-
- #ifdef __TURBOC__
- dmp->f=(VEC)farmalloc((unsigned long)(n*sizeof(double)));
- #else
- dmp->f=(VEC)malloc((unsigned long)(n*sizeof(double)));
- #endif
-
-
- if(dmp->f==(VEC)NULL)
- { sprintf(err_msg,"Field %s[%ld] too large.",tt->s,n);
- t_error(err_msg,1); }
- for(l=0L;l<n;l++) *(dmp->f+l)=0;
- dmp->l=n;
- return;
- }
-
- double *get_field(int nn, T_NODE *tnode, DIM_H *dm)
- {
- T_NODE *tn;
- DIM_H *dmp;
- int i; long n,shift;
-
- tn=tnode->a;
- if(tn==(T_NODE *)NULL || (tn->c!=B_FLD))
- { yyerror("not a field"); return(double *)NULL; }
- if(tn->p==(void *)NULL)
- { yyerror("field with unknown dimension"); return(double *)NULL; }
- dmp=(DIM_H *)(tn->p);
-
- if(dm->n!=dmp->n)
- { yyerror("wrong number of indices"); return(double *)NULL; }
- for(i=0,n=0L,shift=1L;i<dm->n;i++)
- { if((dm->d[i] > dmp->d[i]) || (dm->d[i]<=0))
- { yyerror("index out of range"); return(double *)NULL; }
- n+=(dm->d[i]-1)*shift;
- shift*=dmp->d[i];
- }
- id1=(int)(n%(-nn*8));
- if(nn>0) n*=nn; else n=n/(-nn*8);
- if(n>=dmp->l)
- { yyerror("field length mismatch"); return((double *)NULL); }
- tnode->p=(void *)((dmp->f)+n);
- return((VEC)(tnode->p));
- }
-
- double rnd(double r)
- { return( r*(double)(rand()&0X7FFF)/0X8000L ); }
-
-
- POV_OBJ *plane(VECTOR b,VECTOR a)
- {
- vec0(pv_obj.b); vecx(pv_obj.u); vecy(pv_obj.v); vecz(pv_obj.w);
- sprintf(pv_line,"plane { <%G,%G,%G>, %G }",
- a[0],a[1],a[2],dot(a,b)/vecabs(a));
- pv_obj.c=0; pv_obj.s=pv_line;
- pv_obj.tex=pv_obj.bound=(POV_OBJ *)NULL;
- pv_obj.cnt=1;
- return(&pv_obj);
- }
-
- /* Copies p to pv_obj */
- POV_OBJ *cp_tmp(POV_OBJ *p)
- {
- pv_obj.c=p->c; pv_obj.s=p->s;
- pv_obj.tex=p->tex; pv_obj.bound=p->bound;
- pv_obj.cnt=1;
- vecasn(pv_obj.b,p->b);
- vecasn(pv_obj.u,p->u);
- vecasn(pv_obj.v,p->v);
- vecasn(pv_obj.w,p->w);
- return(&pv_obj);
- }
-
- double obj_rad(POV_OBJ *p)
- { double x,y,z;
- x=vecabs(p->u);
- y=vecabs(p->v);
- z=vecabs(p->w);
- return((x+y+z)/3);
- }
-
- /* create right angle vector */
- void vec90(VECTOR rr,VECTOR v)
- {
- int i,k;
- VECTOR r;
-
- for(i=0,k=0; i<3; i++) { r[i]= (v[i]==0) ? 1 : 0; k+=(v[i]==0); }
- if(!k)
- { for(i=0; i<3; i++) r[i]=1/v[i]; r[2]=-2*r[2]; }
- norm(rr,r);
- return;
- }
-
-
- POV_OBJ *ctds(POV_OBJ *p1, POV_OBJ *p2)
- { double dd,r1,r2,a,sa,r,s1,s2;
- VECTOR v,v1,v2,vu,vv,vw,vb;
-
- vecsub(v,p2->b,p1->b);
- r1=obj_rad(p1); r2=obj_rad(p2);
- r=r1-r2;
- if(r==0)
- {
- vecasn(v1,p1->b);
- vecasn(v2,p2->b);
- s1=r1; s2=r2;
- }
- else
- {
- a=vecabs(v);
- if((a==0) || (a<=fabs(r))) return((POV_OBJ *)NULL);
- sa=r/a; /* sinus alpha */
- dd=sqrt(1/(sa*sa)-1);
-
- /* first cone rad: r1*sa*dd */
- /* second cone rad: r2*sa*dd */
- /* first cone point: $3->b+(v)*sa*r1 */
- /* second cone point: $5->b+(v)*sa*r2 */
-
- norm(v,v);
- s1=r1*sa; s2=r2*sa;
- vecscale(v1,s1,v); vecscale(v2,s2,v);
- vecadd(v1,v1,p1->b); vecadd(v2,v2,p2->b);
- s1*=dd; s2*=dd;
- s1=fabs(s1); s2=fabs(s2);
- }
-
- dd= (s1>s2) ? s1 : s2;
- sprintf(pv_line,"cone {<-1,0,0>,%G,<1,0,0>,%G }",s1/dd,s2/dd);
- vecasn(vb,v1);
- vecsub(vu,v2,v1);
- vecscale(vu,0.5,vu);
- vecadd(vb,vb,vu);
- vec90(vv,vu);
- vecprod(vw,vv,vu);
- norm(vw,vw);
- vecscale(vv,dd,vv);
- vecscale(vw,dd,vw);
-
-
- /* vec0(vb); vecx(vu); vecy(vv); vecz(vw); *//* for debugging */
-
- vecasn(pv_obj.b,vb); vecasn(pv_obj.u,vu);
- vecasn(pv_obj.v,vv); vecasn(pv_obj.w,vw);
- pv_obj.c=(char)0; pv_obj.s=pv_line;
- pv_obj.tex=(p1->tex==(POV_OBJ *)NULL) ? p2->tex : p1->tex;
- pv_obj.bound=(POV_OBJ *)NULL;
- pv_obj.cnt=1;
- return(&pv_obj);
- }
-